/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * <p>https://www.renren.io
 *
 * <p>版权所有，侵权必究！
 */
package cn.sczhyt.modules.sys.controller;

import cn.sczhyt.modules.sys.dao.SysUserDao;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import cn.sczhyt.common.utils.DateUtils;
import cn.sczhyt.common.utils.R;
import cn.sczhyt.common.utils.SmsUtils;
import cn.sczhyt.modules.sys.dao.SysMobileCodeDao;
import cn.sczhyt.modules.sys.entity.SysMobileCodeEntity;
import cn.sczhyt.modules.sys.entity.SysUserEntity;
import cn.sczhyt.modules.sys.form.SysLoginForm;
import cn.sczhyt.modules.sys.service.SysCaptchaService;
import cn.sczhyt.modules.sys.service.SysMobileCodeService;
import cn.sczhyt.modules.sys.service.SysUserService;
import cn.sczhyt.modules.sys.service.SysUserTokenService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.*;

import static cn.sczhyt.common.utils.RandomNumberUtils.getSixCode;

/**
 * 登录相关
 *
 * @author Mark sunlightcs@gmail.com
 */
@Api(tags = "登录")
@RestController
public class SysLoginController extends AbstractController {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserTokenService sysUserTokenService;
    @Autowired
    private SysCaptchaService sysCaptchaService;
    @Autowired
    private SysMobileCodeService sysMobileCodeService;
    @Autowired
    private SysMobileCodeDao mobileCodeDao;
    @Autowired
    private SysUserDao userDao;

    /**
     * 验证码
     */
    @ApiOperation("验证码")
    @GetMapping("captcha.jpg")
    public void captcha(HttpServletResponse response, String uuid) throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");

        // 获取图片验证码
        BufferedImage image = sysCaptchaService.getCaptcha(uuid);

        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        IOUtils.closeQuietly(out);
    }

    /**
     * 获取手机登录验证码
     */
    @ApiOperation("获取手机登录验证码")
    @PostMapping("/login/smsCode")
    public Map<String, Object> getSmsCode(@RequestBody SysLoginForm form)
            throws TencentCloudSDKException {
        System.out.println(form);
        // 判断主要参数参数是否为空
        if (form.getMobile() == null || form.getMobile().equals("")) {
            return R.error(210, "您输入的手机号为空");
        }

        // 手机号登录方式
        SysUserEntity user = sysUserService.queryByMobile(form.getMobile());
        // 账号不存在
        if (user == null) {
            return R.error(202, "该手机号未绑定用户");
        }
        // 获取手机号，并发送短信
        String[] phoneNumbers = {"+86" + form.getMobile()};//需要加国际代码

        // 模板ID,短信登录的模板ID
        String ID = "670615";
        // 随机六位数
        String code = String.valueOf(getSixCode());
        String codeTime = "5"; // 有效期5分钟
        // 放入模板需要的参数
        String[] param = {code, codeTime};
        // 调用发送短信的工具
        SmsUtils.sendSms(phoneNumbers, ID, param);
        // 保存验证码
        SysMobileCodeEntity sysMobileCodeEntity = new SysMobileCodeEntity();
        sysMobileCodeEntity.setMobile(form.getMobile());
        sysMobileCodeEntity.setMsgCode(code);
        sysMobileCodeEntity.setExpireTime(DateUtils.addDateMinutes(new Date(), 5)); // 设置五分钟过期
        //判断验证码是否存在
        if (mobileCodeDao.selectById(form.getMobile()) == null) {

            mobileCodeDao.insert(sysMobileCodeEntity);
        } else {
            mobileCodeDao.updateById(sysMobileCodeEntity);
        }

        return R.ok();
    }

    /**
     * 手机号验证码登录
     */
    @ApiOperation("手机验证码登录")
    @PostMapping("/sys/loginByMobileSMS")
    public Map<String, Object> loginByMobile(@RequestBody SysLoginForm form) {

        // 判断主要手机号参数是否为空
        if (form.getMobile() != null && !form.getMobile().equals("")) {

            // 用户信息
            SysUserEntity user = sysUserService.queryByMobile(form.getMobile());
            // 账号不存在
            if (user == null) {
                return R.error(202, "该手机号未绑定用户");
            }
            // 判断验证码是否正确
            boolean b = sysMobileCodeService.validate(form.getMobile(), form.getMsgCode());
            // 验证码正确 获取用户信息
            if (!b) {
                return R.error(1001, "验证码错误，请重新获取");
            }
            // 账号锁定
            if (user.getStatus() == 0) {
                return R.error(204, "账号已被锁定,请联系管理员");
            }


            //获取上次登录时间
            Optional<Date> prevLoginTime = Optional.ofNullable(user.getLatestLoginTime());
            //设置本次登录时间,上次登录时间
            user.setLatestLoginTime(new Date());
            user.setPrevLoginTime(prevLoginTime.get());
            userDao.updateById(user);


            // 生成token，并保存到数据库
            R r = sysUserTokenService.createToken(user.getUserId());


            return r;


        }

        return R.error(1001, "请输入手机号");
    }

    /**
     * 普通登录
     */
    @ApiOperation("普通登录")
    @PostMapping("/sys/login")
    public Map<String, Object> login(@RequestBody SysLoginForm form) {

        System.out.println(form);
        // 验证码
        boolean captcha = sysCaptchaService.validate(form.getUuid(), form.getCaptcha());
        if (!captcha) {
            return R.error(208, "验证码不正确");
        }
        // 判断主要参数参数是否为空
        if (form.getMobile() != null || form.getUsername() != null) {

            // 手机号登录方式
            if (form.getMobile() != null && !form.getMobile().equals("")) {

                // 用户信息
                SysUserEntity user = sysUserService.queryByMobile(form.getMobile());

                // 账号不存在、密码错误
                if (user == null || !user.getPassword().equals(new Sha256Hash(form.getPassword(), user.getSalt()).toHex())) {
                    return R.error(203, "账号或密码不正确");
                }

                // 账号锁定
                if (user.getStatus() == 0) {
                    return R.error(204, "账号已被锁定,请联系管理员");
                }


                //获取上次登录时间
                Optional<Date> prevLoginTime = Optional.ofNullable(user.getLatestLoginTime());
                //设置本次登录时间,上次登录时间
                user.setLatestLoginTime(new Date());
                user.setPrevLoginTime(prevLoginTime.isPresent() == true ? prevLoginTime.get() : null);
                userDao.updateById(user);


                // 生成token，并保存到数据库
                R r = sysUserTokenService.createToken(user.getUserId());


                return r;
            }

            // 用户名登陆方式
            if (form.getUsername() != null && !form.getUsername().equals("")) {
                // 用户信息
                SysUserEntity user = sysUserService.queryByUserName(form.getUsername());

                // 账号不存在、密码错误
                if (user == null
                        || !user.getPassword()
                        .equals(new Sha256Hash(form.getPassword(), user.getSalt()).toHex())) {
                    return R.error(203, "账号或密码不正确");
                }

                // 账号锁定
                if (user.getStatus() == 0) {
                    return R.error(204, "账号已被锁定,请联系管理员");
                }


                //获取上次登录时间
                Optional<Date> prevLoginTime = Optional.ofNullable(user.getLatestLoginTime());
                //设置本次登录时间,上次登录时间
                user.setLatestLoginTime(new Date());
                user.setPrevLoginTime(prevLoginTime.isPresent() == true ? prevLoginTime.get() : null);
                userDao.updateById(user);


                // 生成token，并保存到数据库
                R r = sysUserTokenService.createToken(user.getUserId());


                return r;
            }
        }
        return R.error(201, "请输入手机号或者登陆用户名");
    }

    /**
     * 退出
     */
    @ApiOperation("退出登录")
    @PostMapping("/sys/logout")
    public R logout() {
        sysUserTokenService.logout(getUserId());
        return R.ok();
    }
}



